package soo;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.imageio.ImageIO;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;

/** 
* 数字验证码识别器（用于识别xxx系统的图片验证码） 
*  
* 算法如下： 分析验证码图片结构，将其分隔成4个独立的数字图片，把四个独立的数字图片处理成单色位图。  
* 把单色位图转换为0、1数组，然后分别和0-9的字模进行匹配，得到图片上的数字信息。 
*  
* @since JDK 1.5.0_8 
*/
public class NumberVerCodeIdentifier {

    static {
        System.setProperty("com.sun.media.jai.disableMediaLib", "true");
    }

    // 字典
    private static String a0 = "001111000111111011100111110000111100001111000011110000111100001111000011111001110111111000111100";

    private static String a1 = "000011000001110000111100011011000100110000001100000011000000110000001100000011000000110000001100";

    private static String a2 = "001111000111111011100011110000110000001100000110000011100001110000111000011000001111111111111111";

    private static String a3 = "001111100111111111000011000000110001111000011110000001110000001111000011111001110111111000111100";

    private static String a4 = "000001100000111000001110000111100011011000110110011001101100011011111111111111110000011000000110";

    private static String a5 = "011111100111111001100000111000001111110011111110110001110000001111000011111001110111111000111100";// 前

    private static String a6 = "001111100111111101100011110000001101110011111110111001111100001111000011011000110111111000111100";

    private static String a7 = "111111111111111100000110000011000000110000011000000110000001100000111000001100000011000000110000";

    private static String a8 = "001111000111111011000011110000111100001101111110011111101100001111000011110000110111111000111100";

    public String recognize(BufferedImage image) {

        String result = "";

        BufferedImage newim[] = new BufferedImage[4];
        if (null == image) {
            throw new RuntimeException("iamage为null");
        }
        // 将图像分成四块，因为要处理的文件有四个数字。

        newim[0] = generateSingleColorBitMap(image.getSubimage(0, 5, 8, 12));
        newim[1] = generateSingleColorBitMap(image.getSubimage(13, 7, 8, 12));
        newim[2] = generateSingleColorBitMap(image.getSubimage(26, 5, 8, 12));
        newim[3] = generateSingleColorBitMap(image.getSubimage(39, 7, 8, 12));

        for (int k = 0; k < 4; k++) {
            int iw = newim[k].getWidth(null);
            int ih = newim[k].getHeight(null);

            StringBuffer numstr = new StringBuffer();
            // 因为是二值图像，这里的方法将像素读取出来的同时，转换为0，1的图像数组。
            for (int i = 0; i < ih; i++) {
                for (int j = 0; j < iw; j++) {

                    int t = newim[k].getRGB(j, i);
                    if (t == -1)
                        numstr.append("0");
                    else
                        numstr.append("1");;

                }
            }
            // 得到像匹配的数字串。
            String aaaaa = numstr.toString();
            if (aaaaa.equals(a0)) {
                result = result + 0;
                // System.out.println(0);
            }

            if (aaaaa.equals(a1)) {
                result = result + 1;// System.out.println(1);
            }
            if (aaaaa.equals(a2)) {
                result = result + 2;// System.out.println(2);
            }
            if (aaaaa.equals(a3)) {
                result = result + 3;// System.out.println(3);
            }

            if (aaaaa.equals(a4)) {
                result = result + 4;// System.out.println(4);
            }
            if (aaaaa.equals(a5)) {
                result = result + 5;// System.out.println(4);
            }
            if (aaaaa.equals(a6)) {
                result = result + 6;// System.out.println(4);
            }
            if (aaaaa.equals(a7)) {
                result = result + 7;// System.out.println(7);
            }
            if (aaaaa.equals(a8)) {
                result = result + 8;// System.out.println(7);
            }
        }
        // System.out.println(result);
        return result;

    }

    /** 
     * 单色位图转换
     * @return 
     */
    private static BufferedImage generateSingleColorBitMap(Image colorImage) {
        BufferedImage image = new BufferedImage(8, 12, BufferedImage.TYPE_BYTE_GRAY);
        Graphics g = image.getGraphics();
        g.drawImage(colorImage, 0, 0, null);
        g.dispose();
        RenderedOp ro = JAI.create("binarize", image, new Double(100));
        BufferedImage bi = ro.getAsBufferedImage();

        return bi;
    }

    /** 
     * 测试 

     */
    public static void main(String args[]) {

        NumberVerCodeIdentifier nvi = new NumberVerCodeIdentifier();

        String res = "";
        try {
            res = nvi.recognize(ImageIO.read(new File("/home/jeffrey/Downloads/img/VerifyCodeCH.aspx.jpeg")));

            // res = nvi.recognize(ImageIO.read(new
            // URL("http://******.com/validationCode.jsp")));
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(res);
    }
}